import * as os from 'os';
import fs from 'fs-extra';
import path from 'path';

import { MinioConfig } from './minioStorage';
import { StorageConfig } from '$domain/model/agent/type';
import { CommandBuilder } from '$domain/service/commandBuilder';
import { isWin, logger, sleep } from '$common';
import { CommandExecuteBuilder } from '$domain/service/commandLineExecutor';
export class StorageCLI {

  public bucket: string;
  public executablePath: string;

  async initialize(storageConfig: StorageConfig) {

    this.bucket = storageConfig.config.bucket;

    const binaryName = isWin ? 'mc.exe' : 'mc';
    const sourceExecutablePath = path.join(__dirname, '../../../bin', binaryName);
    const targetExecutablePath = this.executablePath = path.join(os.homedir(), '.binary', binaryName);

    if (fs.pathExistsSync(sourceExecutablePath)) {
      if (!fs.pathExistsSync(targetExecutablePath)) {

        logger.debug('🚀 storage cli init...');
        fs.ensureDirSync(path.dirname(targetExecutablePath));
        fs.createReadStream(sourceExecutablePath).pipe(fs.createWriteStream(targetExecutablePath));
        fs.chmodSync(targetExecutablePath, 0o777);
        logger.info(`🚀 binary cp done. from ${sourceExecutablePath} to ${targetExecutablePath}`);

        await sleep(1000);

        const { useSSL, host: hostName, port, accessKey, accessSecret } = storageConfig.config as MinioConfig;

        const protocol = `${useSSL ? 'https' : 'http' }`;
        const endpoint = `${protocol}://${hostName}:${port}`;

        const { fullCommand: mcInitCommand } = new CommandBuilder()
          .setExecutable(targetExecutablePath)
          .setCommand('config')
          .setArgs('host', 'add', 'minio', endpoint, accessKey, accessSecret)
          .build();

        try {
          await new CommandExecuteBuilder().build().execute(mcInitCommand);
          logger.info('🍉 init storage CLI client successful');
        } catch (e) {
          logger.error('init storage CLI client failed.');
          throw e;
        }
      } else {
        logger.debug('🚀 storage cli has inited.');
      }
    } else {
      logger.warn(`missing executable: ${sourceExecutablePath}`);
    }
  }

  async fGetObject(objectName: string, filePath: string) {
    const { fullCommand: mcCpCommand } = new CommandBuilder()
      .setExecutable(this.executablePath)
      .setCommand('cp')
      .setArgs(`minio/${this.bucket}/${objectName}`, filePath)
      .build();
    return await new CommandExecuteBuilder().build().execute(mcCpCommand);
  }
}

export const storageCLI = new StorageCLI();